#!/usr/bin/python2
# -*- coding: utf-8 -*-


import threading
import time
import logging
import os
import sys

from eventlet.queue import Empty
from ryu.ofproto import ofproto_v1_3, ofproto_v1_3_parser

# from Queue import Queue
from eventlet import Queue,sleep

from dependency import DependencyGraph,DependencyNode,Operation


class Executor():
    def __init__(self, update_queue,notify_queue, dps, topo):
        # super(Executor, self).__init__()
        assert isinstance(update_queue, Queue)
        assert isinstance(notify_queue, Queue)
        self.__update_queue = update_queue
        self.__dps = dps
        self.__notify_queue = notify_queue
        self.__exec_count = 0
        self.__topo = topo
        self.__merge = True

    def run(self):
        start_time = None
        glist = []
        while True:
            print("exec_count",self.__exec_count)
            if start_time is not None:
                print("time_count", time.time() - start_time)
            try:
                g = self.__update_queue.get(timeout=10)  # TODO for test, wait 10s
                glist.append(g)
            except Empty:
                self.__test(glist)
                sys.stdout.flush()
                os._exit(0)

    def __test(self,l):
        segment = len(l)//10
        for k in range(segment):
            start = k*10
            num = [len(l[i].nodes) for i in range(start,start+11)]
            # print("num",num)
            count1 = [sum(num[:i]) for i in range(1,11)]
            count2 = [ len(self.__merge_list(l[start:start+i]).nodes)
                    for i in range(1,11)]
            print("count1[%d]=%s ; count2[%d]=%s;"%(k,count1,k,count2))



    def __merge_list(self,glist):
        assert len(glist)>0
        partition_map = dict()

        for g in glist:
            key = (g.ip1,g.ip2)
            val = partition_map.get(key)
            if val is None:
                partition_map[key]=[g]
            else:
                val.append(g)

        for key,val in partition_map.items():
            if len(val)<=1:
                partition_map[key] = val[0]
            else:
                partition_map[key] = DependencyGraph.construct(
                    val[0].path1,
                    val[-1].path2,
                    key[0],
                    key[1]
                )
        return DependencyGraph.merge_different_ippair(partition_map.values())